//@version=6
// Nifty Participants - Top 10 (Updated)
indicator('Nifty Participants - Top 10 (Updated)', overlay=true)

//───────────────────────
// INPUT SETTINGS
//───────────────────────
source      = input(defval=close, title='Source')
rowsToShow  = input.int(title='No. of Top Participants to show', defval=5, minval=1, maxval=10, tooltip='No. of rows')

rsiVal      = input.int(defval=14, title='RSI Input')
rsiMax      = input.float(defval=60, title='RSI Top')
rsiMin      = input.float(defval=40, title='RSI Bottom')

timeFrame   = input.timeframe(title='Timeframe', defval='D')
indexChoice = input.symbol(defval='NIFTY', title='Index Symbol', group='Index Settings')

// Display settings
textSize = input.string(
     title='Text Size',
     defval=size.small,
     options=[size.huge, size.auto, size.large, size.normal, size.small, size.tiny],
     group='Table Settings')

tablePosition = input.string(
     title='Table Position',
     defval=position.bottom_right,
     options=[position.bottom_right, position.bottom_left, position.bottom_center,
              position.top_right, position.top_left, position.top_center],
     group='Table Settings')

// Volume spike settings
volLookback = input.int(title='Volume Lookback Period', defval=50, minval=10, maxval=200, group='Volume Settings')

volSpikeThreshold = input.float(
     title='Volume Spike Threshold (x)',
     defval=2.0,
     minval=1.0,
     maxval=10.0,
     step=0.5,
     tooltip='Volume spike when current volume is X times average',
     group='Volume  Settings')

//───────────────────────
// INDEX DATA
//───────────────────────
[indexLTP, prevIndexLTP, indexRSI, indexVWAP, indexPrevDayHigh, indexPrevDayLow, indexVolume, indexAvgVolume] = request.security(indexChoice, timeFrame, [close, close[1], ta.rsi(source, rsiVal), ta.vwap, high[1], low[1], volume, ta.sma(volume, volLookback)])


indexChange        = indexLTP - prevIndexLTP
indexPercentChange = indexChange / prevIndexLTP * 100.0
pointChange        = indexLTP / 100.0
indexVolSpike      = indexVolume > (indexAvgVolume * volSpikeThreshold)

//───────────────────────
// COLOR SETTINGS
//───────────────────────
bullColor        = input.color(title='Bull',         defval=#26a69a, group='Colors')
bearColor        = input.color(title='Bear',         defval=#ef5350, group='Colors')
neutralColor     = input.color(title='Neutral',      defval=#ff9800, group='Colors')
tableHeaderColor = input.color(title='Table Header', defval=#37474f, group='Colors')
headerTextColor  = input.color(title='Header Text',  defval=color.white, group='Colors')
textColor        = input.color(title='Table Text',   defval=color.white, group='Colors')
tableBorderColor = input.color(title='Table Border', defval=#263238, group='Colors')
indexColumnColor = input.color(title='Index Column', defval=#263238, group='Colors')
prevDayHighColor = input.color(title='Prev Day H Column', defval=#1e88e5, group='Colors')
prevDayLowColor  = input.color(title='Prev Day L Column', defval=#1e88e5, group='Colors')

//───────────────────────
// TABLE
//───────────────────────
var indicatorTable = table.new(
     position     = tablePosition,
     columns      = 12,
     rows         = 50,
     frame_color  = #37474f,
     frame_width  = 2,
     border_width = 1,
     border_color = tableBorderColor)

// Column visibility settings
showLTP         = input.bool(title='LTP',           defval=true,  group='Columns')
showChange      = input.bool(title='Change',        defval=true,  group='Columns')
showChangePer   = input.bool(title='Change %',      defval=true,  group='Columns')
showShare       = input.bool(title='Share',         defval=true,  group='Columns')
showRSI         = input.bool(title='RSI',           defval=true,  group='Columns')
showVWAP        = input.bool(title='VWAP',          defval=true,  group='Columns')
showVolSpike    = input.bool(title='Volume Spike',  defval=true,  group='Columns')
showPrevDayHigh = input.bool(title='Prev Day High', defval=false, group='Columns')
showPrevDayLow  = input.bool(title='Prev Day Low',  defval=false, group='Columns')

// Index cell colors
rsiIndexColor      = indexRSI >= rsiMax ? bullColor : indexRSI <= rsiMin ? bearColor : neutralColor
vwapIndexColor     = indexLTP > indexVWAP ? bullColor : indexLTP < indexVWAP ? bearColor : neutralColor
ltpIndexColor      = indexLTP > indexPrevDayHigh ? bullColor : indexLTP < indexPrevDayLow ? bearColor : neutralColor
volSpikeIndexColor = indexVolSpike ? bullColor : neutralColor

// Helper
convertToString(number) =>
    str.tostring(number, '0.00')

//───────────────────────
// HEADER ROW (ROW 0)
//───────────────────────
int colIndex = 0

table.cell(table_id=indicatorTable, column=colIndex, row=0,
           text='Symbol', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
colIndex += 1

if showLTP
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='LTP', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showChange
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='Chg', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showChangePer
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='Chg%', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showShare
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='Share', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showRSI
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='RSI', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showVWAP
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='VWAP', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showVolSpike
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='Vol Ratio', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showPrevDayHigh
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='Prev Day H', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)
    colIndex += 1
if showPrevDayLow
    table.cell(table_id=indicatorTable, column=colIndex, row=0,
               text='Prev Day L', bgcolor=tableHeaderColor, text_color=headerTextColor, text_size=textSize)

//───────────────────────
// INDEX ROW (ROW 1)
//───────────────────────
colIndex := 0
table.cell(table_id=indicatorTable, column=colIndex, row=1,
           text=indexChoice, text_halign=text.align_left,
           bgcolor=indexColumnColor, text_color=textColor, text_size=textSize)
colIndex += 1

if showLTP
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexLTP), text_halign=text.align_left,
               bgcolor=ltpIndexColor, text_color=textColor, text_size=textSize)
    colIndex += 1
if showChange
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexChange), text_halign=text.align_left,
               bgcolor=indexChange > 0 ? bullColor : bearColor,
               text_color=textColor, text_size=textSize)
    colIndex += 1
if showChangePer
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexPercentChange), text_halign=text.align_left,
               bgcolor=indexPercentChange > 0 ? bullColor : bearColor,
               text_color=textColor, text_size=textSize)
    colIndex += 1
if showShare
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text='-', text_halign=text.align_left,
               bgcolor=tableHeaderColor, text_color=textColor, text_size=textSize)
    colIndex += 1
if showRSI
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexRSI), text_halign=text.align_left,
               bgcolor=rsiIndexColor, text_color=textColor, text_size=textSize)
    colIndex += 1
if showVWAP
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexVWAP), text_halign=text.align_left,
               bgcolor=vwapIndexColor, text_color=textColor, text_size=textSize)
    colIndex += 1
if showVolSpike
    safeIndexAvgVol = nz(indexAvgVolume, indexVolume)
    indexVolRatio   = indexVolume / safeIndexAvgVol
    indexVolText    = convertToString(indexVolRatio) + 'x'
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=indexVolText, text_halign=text.align_left,
               bgcolor=volSpikeIndexColor, text_color=textColor, text_size=textSize)
    colIndex += 1
if showPrevDayHigh
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexPrevDayHigh), text_halign=text.align_left,
               bgcolor=prevDayHighColor, text_color=textColor, text_size=textSize)
    colIndex += 1
if showPrevDayLow
    table.cell(table_id=indicatorTable, column=colIndex, row=1,
               text=convertToString(indexPrevDayLow), text_halign=text.align_left,
               bgcolor=prevDayLowColor, text_color=textColor, text_size=textSize)

//───────────────────────
// FUNCTION TO DISPLAY STOCK DATA
//───────────────────────
data(int i, string sym, float weightage) =>
    [currentClose, prevClose, currentRSI, vwapValue, prevHigh, prevLow, currentVol, avgVol] = request.security(sym, timeFrame,[close, close[1], ta.rsi(source, rsiVal), ta.vwap, high[1], low[1], volume, ta.sma(volume, volLookback)])

    changeValue        = currentClose - prevClose
    changePer          = changeValue / prevClose
    participationValue = indexLTP * weightage * changePer

    bgcol       = participationValue > 0 ? bullColor : bearColor
    rsiColor    = currentRSI >= rsiMax ? bullColor : currentRSI <= rsiMin ? bearColor : neutralColor
    vwapColor   = currentClose > vwapValue ? bullColor : currentClose < vwapValue ? bearColor : neutralColor
    ltpColor    = currentClose > prevHigh ? bullColor : currentClose < prevLow ? bearColor : neutralColor
    safeAvgVol  = nz(avgVol, currentVol)
    volSpike    = currentVol > (safeAvgVol * volSpikeThreshold)
    volSpikeCol = volSpike ? bullColor : neutralColor

    if i <= rowsToShow
        int colIdx = 0

        table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                   text=sym, text_halign=text.align_left,
                   bgcolor=indexColumnColor, text_color=textColor, text_size=textSize)
        colIdx += 1

        if showLTP
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(currentClose), text_halign=text.align_left,
                       bgcolor=ltpColor, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showChange
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(changeValue), text_halign=text.align_left,
                       bgcolor=bgcol, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showChangePer
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(changePer * 100.0), text_halign=text.align_left,
                       bgcolor=bgcol, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showShare
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(participationValue), text_halign=text.align_left,
                       bgcolor=bgcol, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showRSI
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(currentRSI), text_halign=text.align_left,
                       bgcolor=rsiColor, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showVWAP
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(vwapValue), text_halign=text.align_left,
                       bgcolor=vwapColor, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showVolSpike
            volRatio = currentVol / safeAvgVol
            volText  = convertToString(volRatio) + 'x' + (volSpike ? ' 🔥' : '')
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=volText, text_halign=text.align_left,
                       bgcolor=volSpikeCol, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showPrevDayHigh
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(prevHigh), text_halign=text.align_left,
                       bgcolor=prevDayHighColor, text_color=textColor, text_size=textSize)
            colIdx += 1
        if showPrevDayLow
            table.cell(table_id=indicatorTable, column=colIdx, row=i + 1,
                       text=convertToString(prevLow), text_halign=text.align_left,
                       bgcolor=prevDayLowColor, text_color=textColor, text_size=textSize)

//───────────────────────
// TOP 10 NIFTY STOCKS (STATIC LIST)
//───────────────────────
// Weightages in decimal format (12.78% = 0.1278)
participant1Name   = 'HDFCBANK'
part1Participation = input.float(title=participant1Name + ' weightage', defval=0.1278, group='Weightage')

participant2Name   = 'RELIANCE'
part2Participation = input.float(title=participant2Name + ' weightage', defval=0.0853, group='Weightage')

participant3Name   = 'ICICIBANK'
part3Participation = input.float(title=participant3Name + ' weightage', defval=0.0814, group='Weightage')

participant4Name   = 'BHARTIARTL'
part4Participation = input.float(title=participant4Name + ' weightage', defval=0.0475, group='Weightage')

participant5Name   = 'INFY'
part5Participation = input.float(title=participant5Name + ' weightage', defval=0.0453, group='Weightage')

participant6Name   = 'LT'
part6Participation = input.float(title=participant6Name + ' weightage', defval=0.0401, group='Weightage')

participant7Name   = 'ITC'
part7Participation = input.float(title=participant7Name + ' weightage', defval=0.0343, group='Weightage')

participant8Name   = 'SBIN'
part8Participation = input.float(title=participant8Name + ' weightage', defval=0.0329, group='Weightage')

participant9Name   = 'AXISBANK'
part9Participation = input.float(title=participant9Name + ' weightage', defval=0.0299, group='Weightage')

participant10Name   = 'TCS'
part10Participation = input.float(title=participant10Name + ' weightage', defval=0.0265, group='Weightage')

// Call data function for each stock
data(1,  participant1Name,  part1Participation)
data(2,  participant2Name,  part2Participation)
data(3,  participant3Name,  part3Participation)
data(4,  participant4Name,  part4Participation)
data(5,  participant5Name,  part5Participation)
data(6,  participant6Name,  part6Participation)
data(7,  participant7Name,  part7Participation)
data(8,  participant8Name,  part8Participation)
data(9,  participant9Name,  part9Participation)
data(10, participant10Name, part10Participation)
